"""LLM Provider抽象层"""

from abc import ABC, abstractmethod
from typing import Dict, Any, Optional, Generator, List
import numpy as np


class BaseLLMProvider(ABC):
    """LLM提供商的基础抽象类"""
    
    def __init__(self, config: Dict[str, Any]):
        """初始化LLM提供商
        
        Args:
            config: 配置参数，包含模型名称、温度等
        """
        self.config = config
        self.model = None
        self.tokenizer = None
        self.embedding_model = None
        
    @abstractmethod
    def load_model(self):
        """加载模型"""
        pass
    
    @abstractmethod
    def generate(self, prompt: str, **kwargs) -> str:
        """生成文本响应
        
        Args:
            prompt: 输入提示
            **kwargs: 其他生成参数
        
        Returns:
            生成的文本
        """
        pass
    
    @abstractmethod
    def generate_stream(self, prompt: str, **kwargs) -> Generator[str, None, None]:
        """流式生成文本响应
        
        Args:
            prompt: 输入提示
            **kwargs: 其他生成参数
        
        Yields:
            文本片段
        """
        pass
    
    @abstractmethod
    def generate_embedding(self, text: str) -> np.ndarray:
        """生成文本嵌入
        
        Args:
            text: 输入文本
        
        Returns:
            嵌入向量
        """
        pass
    
    @abstractmethod
    def generate_embeddings(self, texts: List[str]) -> List[np.ndarray]:
        """批量生成文本嵌入
        
        Args:
            texts: 输入文本列表
        
        Returns:
            嵌入向量列表
        """
        pass
    
    @property
    def is_model_loaded(self) -> bool:
        """检查模型是否已加载"""
        return self.model is not None
    
    def close(self):
        """关闭模型资源"""
        pass


class LLMProviderFactory:
    """LLM提供商工厂类"""
    
    _providers = {}
    
    @classmethod
    def register_provider(cls, name: str, provider_class):
        """注册LLM提供商
        
        Args:
            name: 提供商名称
            provider_class: 提供商类
        """
        cls._providers[name] = provider_class
    
    @classmethod
    def create_provider(cls, name: str, config: Dict[str, Any]) -> BaseLLMProvider:
        """创建LLM提供商实例
        
        Args:
            name: 提供商名称
            config: 配置参数
        
        Returns:
            LLM提供商实例
        
        Raises:
            ValueError: 如果提供商不存在
        """
        provider_class = cls._providers.get(name)
        if not provider_class:
            raise ValueError(f"未知的LLM提供商: {name}")
        return provider_class(config)
    
    @classmethod
    def get_available_providers(cls) -> List[str]:
        """获取所有可用的LLM提供商
        
        Returns:
            提供商名称列表
        """
        return list(cls._providers.keys())